/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "布局.h"

#include "intern/ui数值部件.h"
#include "intern/ui容器部件.h"




void f_填充布局(C_Widget* r, C_Widget** w, uint32 num) {
	C_Widget* root = ((C_Widget*)r);

	for (uint32 i = 0; i < num; ++i) {
		C_Widget& widget = *((C_Widget*)w[i]);

		if (widget.mf_布局Fun) {
			widget.m_Pos = root->m_Pos;
			widget.m_Size = root->m_Size;
		}
		
		//((C_Widget*)r)->f_setMove(widget.f_getPos());
		//((C_Widget*)r)->m_Size = widget.m_Size;
	}
}

void f_散列布局(C_Widget* r, C_Widget** w, uint32 num) {
	for (uint32 i = 0; i < num; ++i) {

	}
}

float32 f_HBOX布局(vec2 pos, vec2 size, C_Widget** w, uint32 num) {
	float32 布局组件新宽度 = pos.x;
	float32 总固定宽度 = pos.x;
	uint32	伸展组件数量 = 0;

	for (uint16 i = 0; i < num; ++i) {
		if (!(w[i]->m_开启渲染)) continue;

		if (w[i]->m_是否延展.x) {
			++伸展组件数量;
		}
		else {
			总固定宽度 += w[i]->m_Size.x;
		}
		总固定宽度 += w[i]->m_间隔宽度;
	}
	总固定宽度 += w[num-1]->m_间隔宽度;
	//总固定宽度 = DEF_Min(总固定宽度, size.x);


	float32 伸展高度 = 0.0;
	if (伸展组件数量) {
		伸展高度 = size.x - 总固定宽度;
		伸展高度 /= 伸展组件数量;
		伸展高度 = DEF_Max(0.0, 伸展高度);
	}



	for (uint16 i = 0; i < num; ++i) {
		if (w[i]->m_开启渲染) {
			布局组件新宽度 += w[i]->m_间隔宽度;
			pos.x = (布局组件新宽度);

			w[i]->f_setPos(pos);

			if (w[i]->m_是否延展.x) {
				size.x = 伸展高度 * w[i]->m_延申比;
				//size.y = size.y;
			}
			else {
				size.x = w[i]->m_Size.x;
				//size.y = w[i]->m_Size.y;
			}
			
			布局组件新宽度 += size.x;
			w[i]->f_setSize(size);
		}
	}


	return 布局组件新宽度;
}

float32 f_VBOX布局(vec2 pos, vec2 size, C_Widget** w, uint32 num) {
	float32 布局组件新高度 = 0;
	
	float32 总固定高度 = pos.y;
	uint32	伸展组件数量 = 0;
	for (uint16 i = 0; i < num; ++i) {
		if (!(w[i]->m_开启渲染)) continue;

		if (w[i]->m_是否延展.y) {
			++伸展组件数量;
		}
		else {
			总固定高度 += w[i]->m_Size.y;
		}
		总固定高度 += w[i]->m_间隔宽度;
	}
	总固定高度 += w[num - 1]->m_间隔宽度;


	float32 伸展高度 = 0.0;
	if (伸展组件数量) {
		伸展高度 = size.y - 总固定高度;
		伸展高度 /= 伸展组件数量;
		伸展高度 = DEF_Max(0.0, 伸展高度);
	}



	for (uint16 i = 0; i < num; ++i) {
		if (w[i]->m_开启渲染) {
			
			pos.y = 布局组件新高度;

			w[i]->f_setPos(pos);

			if (w[i]->m_是否延展.y) {
				//size.x = size.x;
				size.y = 伸展高度 * w[i]->m_延申比;
			}
			else {
				//size.x = w[i]->m_Size.x;
				size.y = w[i]->m_Size.y;
			}

			布局组件新高度 += size.y + w[i]->m_间隔宽度;

			w[i]->f_setSize(size);
		}
	}
	
	return 布局组件新高度;
}

void f_HBOX布局(C_Widget* r, C_Widget** w, uint32 num)
{
	if (!num)return;

	float32 布局组件新宽度 = 0;
	//vec2 pos = r->m_Pos;
	vec2 pos = { float32(r->m_间隔宽度), float32(r->m_间隔宽度) };
	vec2 size = r->m_Size;
	size.x -= r->m_间隔宽度*2;
	size.y -= r->m_间隔宽度*2;


	float32 总固定宽度 = pos.x;
	uint32	伸展组件数量 = 0;
	for (uint16 i = 0; i < num; ++i) {
		if (!(w[i]->m_开启渲染)) continue;

		if (w[i]->m_是否延展.x) {
			++伸展组件数量;
		}
		else {
			总固定宽度 += w[i]->m_Size.x;
		}
		总固定宽度 += w[i]->m_间隔宽度;
	}
	//总固定高度 += w[num - 1]->m_间隔宽度;


	float32 伸展宽度 = 0.0;
	if (伸展组件数量) {
		伸展宽度 = size.x - 总固定宽度;
		伸展宽度 /= 伸展组件数量;
		伸展宽度 = DEF_Max(0.0, 伸展宽度);
	}



	for (uint16 i = 0; i < num; ++i) {
		if (w[i]->m_开启渲染) {
			w[i]->f_setPos(pos);

			pos.x += w[i]->m_间隔宽度;
			//pos.y = (布局组件新高度);
			if (w[i]->m_是否延展.x) {
				//size.x = size.x;
				size.x = 伸展宽度 * w[i]->m_延申比;
			}
			else {
				size.x = w[i]->m_Size.x;
			}

			pos.x += size.x;
			w[i]->f_setSize(size);
		}
	}
}

void f_VBOX布局(C_Widget* r, C_Widget** w, uint32 num) {
	if (!num)return;

	float32 布局组件新高度 = 0;
	//vec2 pos = r->m_Pos;
	vec2 pos = { float32(r->m_间隔宽度), float32(r->m_间隔宽度) };
	vec2 size	= r->m_Size;
	size.x -= r->m_间隔宽度 * 2;
	size.y -= r->m_间隔宽度 * 2;


	float32 总固定高度 = pos.y;
	uint32	伸展组件数量 = 0;
	for (uint16 i = 0; i < num; ++i) {
		if (!(w[i]->m_开启渲染)) continue;

		if (w[i]->m_是否延展.y) {
			++伸展组件数量;
		}
		else {
			总固定高度 += w[i]->m_Size.y;
		}
		总固定高度 += w[i]->m_间隔宽度;
	}
	//总固定高度 += w[num - 1]->m_间隔宽度;



	float32 伸展高度 = 0.0;
	if (伸展组件数量) {
		伸展高度 = size.y - 总固定高度;
		伸展高度 /= 伸展组件数量;
		伸展高度 = DEF_Max(0.0, 伸展高度);
	}
	




	for (uint16 i = 0; i < num; ++i) {
		if (w[i]->m_开启渲染) {
			w[i]->f_setPos(pos);

			pos.y += w[i]->m_间隔宽度;
			//pos.y = (布局组件新高度);
			if (w[i]->m_是否延展.y) {
				//size.x = size.x;
				size.y = 伸展高度 * w[i]->m_延申比;
			}
			else {
				size.y = w[i]->m_Size.y;
			}

			pos.y += size.y;
			w[i]->f_setSize(size);
		}
	}
}



float32 f_Layout_网格(vec2 pos, vec2 size, C_Widget** w, uint32 num)
{
	uint32 平方根 = sqrtf(num);
	float32 宽度 = size.x / 平方根;
	float32 高度 = size.y / 平方根;
	for (uint32 y = 0; y < 平方根; ++y) {
		for (uint32 x = 0; x < 平方根; ++x) {
			uint32 id = 平方根 * y + x;
			w[id]->f_setPos({ x * 宽度, y * 高度 });
			w[id]->f_setSize({ 宽度, 高度 });
		}

	}
	return 0;
}

void f_Layout_网格(C_Widget* r, C_Widget** w, uint32 num)
{
	vec2 size = r->m_Size;

	uint32 平方根 = sqrtf(num);
	float32 宽度 = size.x / 平方根;
	float32 高度 = size.y / 平方根;
	for (uint32 y = 0; y < 平方根; ++y) {
		for (uint32 x = 0; x < 平方根; ++x) {
			uint32 id = 平方根 * y + x;
			w[id]->f_setPos({ x * 宽度, y * 高度 });
			w[id]->f_setSize({ 宽度, 高度 });
		}
	}
}


float32 f_HBOX固定布局(float32 maxWidth, C_Widget** w, uint32 num, vec2 offset, float32 间隔) {
	vec2 pos = offset;
	//vec2 size = maxWidth;
	float32 布局组件新跨度 = offset.x * 2;
	for (uint16 i = 0; i < num; ++i) {
		if (w[i]->m_开启渲染) {
			w[i]->f_setPos(pos);
			w[i]->f_setW(maxWidth);

			pos.x += w[i]->m_Size.x + 间隔;

			布局组件新跨度 += w[i]->m_Size.x + 间隔;
		}
	}

	return 布局组件新跨度;
}

float32 f_VBOX固定布局(float32 maxWidth, C_Widget** w, uint32 num, vec2 offset, float32 间隔) {
	vec2 pos = offset;
	//vec2 size = maxWidth;

	float32 布局组件新高度 = offset.y*2;
	for (uint16 i = 0; i < num; ++i) {
		if (w[i]->m_开启渲染) {
			w[i]->f_setPos(pos);
			w[i]->f_setW(maxWidth);

			pos.y += w[i]->m_Size.y + 间隔;

			布局组件新高度 += w[i]->m_Size.y + 间隔;
		}
	}
	
	return 布局组件新高度;
}

void f_Layout_网格(C_Widget* r, C_Widget** w, uint32 num, uint32 横向数量, float32 边距, const vec2& 偏移) {
	uint32 行数量 = num / 横向数量;

	float32 size = ( (r->m_Size.x - 边距*2) - r->m_间隔宽度*(横向数量+1)) / 横向数量;
	float32 higth = ( (r->m_Size.y - 边距*2) - r->m_间隔宽度*(行数量+1)) / 行数量;
	//r->f_setSize({size * 横向数量, size * 行数量});

	for (uint32 i = 0; i < 行数量; ++i) {
		vec2 pos = {float32(r->m_间隔宽度), (higth + r->m_间隔宽度) * i + r->m_间隔宽度 + 边距};
		for (uint32 j = 0; j < 横向数量; ++j) {
			uint32 index = i*横向数量 + j;
			pos.x = (size + r->m_间隔宽度) * j + r->m_间隔宽度 + 边距;
			w[index]->f_setPos(pos);
			w[index]->f_setSize({size, higth});
		}
	}
}

void f_Layout_网格(C_Widget** w, uint32 num, uint32 横向数量, float32 边距, const vec2& 偏移, const vec2& 大小) {
	uint32 行数量 = num / 横向数量;

	float32 size = ((大小.x - 边距 * 2) - 边距 * (横向数量 + 1)) / 横向数量;
	float32 higth = ((大小.y - 边距 * 2) - 边距 * (行数量 + 1)) / 行数量;
	//r->f_setSize({size * 横向数量, size * 行数量});

	for (uint32 i = 0; i < 行数量; ++i) {
		vec2 pos = { float32(边距), (higth + 边距) * i + 边距 + 边距 };
		for (uint32 j = 0; j < 横向数量; ++j) {
			uint32 index = i * 横向数量 + j;
			pos.x = (size + 边距) * j + 边距*2;
			w[index]->f_setPos(pos + 偏移);
			w[index]->f_setSize({ size, higth });
		}
	}
}

void f_布局_纵向滚动条(C_Widget* r, vec2 size, float32 间隙) {
	assert(dynamic_cast<C_滚动条*>(r));
	C_滚动条* 滚动 = (C_滚动条*)r;

	滚动->f_setPos({ size.x - 滚动->m_Size.x - 间隙, 间隙 });
	滚动->f_setH(size.y - 滚动->m_Size.x - 间隙 * 2);
}

void f_布局_双向滚动条(C_Widget* r, E_方向 方向, float32 间隙) {
	C_滚动框* 滚动框 = dynamic_cast<C_滚动框*>(r);
	if ((滚动框->m_双向滚动条) == nullptr) return;

	if (!(滚动框->m_双向滚动条->m_H) || !(滚动框->m_双向滚动条->m_V)) return;

	vec2 size = 滚动框->m_Size;
	//auto e = 滚动->f_get更新部件();

	switch (方向)
	{
	case E_方向::e_横向: {
		C_滚动条* 滚动 = 滚动框->m_双向滚动条->m_H;

		滚动->f_setPos({ 间隙, size.y - 滚动框->m_滚动条厚度 - 间隙 });
		滚动->f_setSize({ size.x - 滚动框->m_滚动条厚度 - 间隙 * 2 , 滚动框->m_滚动条厚度 });

		break;
	}

	case E_方向::e_纵向: {
		C_滚动条* 滚动 = 滚动框->m_双向滚动条->m_V;

		滚动->f_setPos({ size.x - 滚动框->m_滚动条厚度 - 间隙, 间隙 });
		滚动->f_setSize({ 滚动框->m_滚动条厚度, size.y - 滚动框->m_滚动条厚度 - 间隙 * 2 });
		break;
	}
	default:
		break;
	}
	

	//size = 滚动->m_Size;
	/*float32 h = w[0]->m_Size.y * (w[0]->m_Size.y / *(V滚动->m_映射最大值));
	if (h > w[0]->m_Size.y) h = w[0]->m_Size.y;
	else if (h < 滚动框->m_滚动条厚度) h = 滚动框->m_滚动条厚度;
	纵向滚动条按钮.m_W[0]->f_setH(h);
	纵向滚动条按钮.m_W[0]->f_setX(w[0]->m_Pos.x);

	size = H滚动->m_Size;
	
	h = w[1]->m_Size.x * (w[1]->m_Size.x / *(H滚动->m_映射最大值));
	if (h > w[1]->m_Size.x) h = w[1]->m_Size.x;
	else if (h < 滚动框->m_滚动条厚度) h = 滚动框->m_滚动条厚度;
	Hsw.m_W[0]->f_setW(h);*/



}



void f_布局_滚动框视口(C_Widget* r, C_Widget* view) {
	if (r->m_扩展视口属性) {
		f_Widget_应用视口缩放(r, view);
	} else {
		C_滚动框* 滚动框 = dynamic_cast<C_滚动框*>(r);

		//滚动框->m_View->f_setSize(vec_Max(滚动框->f_getSize(), 滚动框->m_View->m_MinSize));
		if (滚动框->m_横向滚动条) {
			float32 w = DEF_Max(滚动框->m_Size.x, 滚动框->m_View->m_Size.x);
			w = DEF_Min(滚动框->m_父部件->m_Size.x, w);
			//滚动框->f_setW(w);

		} else {
			滚动框->m_View->f_setW(滚动框->m_Size.x);
		}

		if (滚动框->m_纵向滚动条) {
			float32 h = DEF_Max(滚动框->m_Size.y, 滚动框->m_View->m_Size.y);
			h = DEF_Min(滚动框->m_父部件->m_Size.y, h);
			//滚动框->f_setH(h);

		} else {
			滚动框->m_View->f_setH(滚动框->m_Size.y);
		}

		if (滚动框->m_横向滚动条 && 滚动框->m_纵向滚动条) {
			滚动框->m_View->f_setSize(vec_Max(滚动框->f_getSize(), 滚动框->m_View->m_MinSize));
		}

	}

}

bool f_布局_扩展视口纵向滚动(C_Widget* self, C_Widget* view, float32 滚动步进) {
	float32 边框大小 = self->m_Size.y;

	float32 步进 = view->m_扩展视口属性->m_中心.y + 滚动步进;
	self->m_绘制属性更新 = true;

	if (view->m_Size.y + 步进 <= 边框大小) {
		步进 = (边框大小 - view->m_Size.y);
		//return true;
	}
	if (步进 > 0) {
		view->m_扩展视口属性->m_中心.y = 0;
		return true;
	}

	view->m_扩展视口属性->m_中心.y = 步进;

	return true;
}

bool f_布局_组件纵向滚动(C_Widget* self, C_Widget* view, float32 滚动步进) {
	float32 边框大小 = self->m_Size.y;

	float32 步进 = view->m_Pos.y + 滚动步进;
	self->m_绘制属性更新 = true;

	if (view->m_Size.y + 步进 <= 边框大小) {
		步进 = (边框大小 - view->m_Size.y);
		//return true;
	}
	if (步进 > 0) {
		view->m_Pos.y = 0;
		return true;
	}

	view->m_Pos.y = 步进;

	return true;
}

void on_滚动框_列表布局(C_Widget* self, C_Widget** w, uint32 num) {
	
}


void f_widget_layout_V滚动钳制(float32& 当前滚动坐标, float32 size, ivec2 行列, float32 项高度, uint32 num) {
	if (当前滚动坐标 > 0) 当前滚动坐标 = 0;
	if (num > 行列.y * 行列.x) {
		项高度 *= 行列.x + 1;
	}
	else {
		项高度 *= 行列.x;
	}

	if (项高度 < size) {
		当前滚动坐标 = 0;
	}
	else {
		if (行列.x && 当前滚动坐标 < 0) {
			if ((项高度 + 当前滚动坐标) < size) {
				当前滚动坐标 = size - 项高度;
			}
		}
	}
}

vec2 f_widget_get文字绘制据中偏移(C_Widget* w, const std::wstring& tex, const S_Font& 字体,  float32 间隔) {
	vec2 offset = { 10, 2 };
	//offset.y = (w->m_Size.y - 字体.m_字号) * 0.3;
	offset.y = 字体.m_字号 * -0.1;

	offset.x = f_surface_get字符串宽度(字体, tex, 间隔);
	offset.x = (w->m_Size.x - offset.x) * 0.5;

	return offset;
}

vec2 f_widget_get文字绘制据中偏移(const vec2& size, const std::wstring& text, const S_Font& 字体, float32 间隔) {
	vec2 offset = { 0, 0 };
	
	offset.y = size.y * 0.5 - 字体.m_字号 * 0.65;
	offset.y = 0;

	offset.x = f_surface_get字符串宽度(字体, text, 间隔);
	offset.x = (size.x - offset.x) * 0.5;

	return offset;
}

vec2 f_widget_get文字左对齐偏移位置(const vec2& size, const std::wstring& text, const S_Font& 字体, float32 间隔)
{
	vec2 offset = { 0, 0 };

	offset.y = size.y * 0.5 - 字体.m_字号 * 0.65;

	return offset;
}






void S_填充布局::f_poll(C_Widget** ws, uint32 num) {
	for (uint32 i = 0; i < num; ++i) {
		ws[i]->f_setSize(m_Size);
	}
}

void S_比例布局::f_poll(C_Widget** ws, uint32 num) {

	for (uint32 i = 0; i < num; ++i) {
		ws[i]->f_setPos(m_大小 * m_位置比例);
		ws[i]->f_setSize(m_大小 * m_大小比例);
	}
}
